package org.easymodelers.gmf.utils;

import org.easymodelers.gmf.utils.GmfModelsUtils;
import org.easymodelers.gmf.utils.MetaModelUtils;
import org.easymodelers.modeler.data.Element;
import org.easymodelers.modeler.data.ElementLabel;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.gmf.gmfgraph.Canvas;
import org.eclipse.gmf.gmfgraph.DiagramLabel;
import org.eclipse.gmf.gmfgraph.Node;
import org.eclipse.gmf.mappings.Mapping;
import org.eclipse.gmf.tooldef.AbstractTool;
import org.eclipse.gmf.tooldef.CreationTool;
import org.eclipse.gmf.tooldef.Palette;
import org.eclipse.gmf.tooldef.ToolRegistry;

public class ModelsManager {
	private Canvas canvas;
	private ToolRegistry toolRegistry;
	private Mapping mapping;
	private EPackage metaModel;

	public ModelsManager(Canvas canvas) {
		this(canvas, null, null, null);
	}

	public ModelsManager(ToolRegistry toolRegistry) {
		this(null, toolRegistry, null, null);
	}

	public ModelsManager(Canvas canvas, ToolRegistry toolRegistry,
								Mapping mapping, EPackage metaModel) {
		this.canvas = canvas;
		this.toolRegistry = toolRegistry;
		this.mapping = mapping;
		this.metaModel = metaModel;
	}

	// Graph model
	
	public Canvas getCanvas() {
		return canvas;
	}

	public Node getNodeForElement(Element element) {
		return GmfModelsUtils.getNodeForElement(element, getCanvas());
	}

	public DiagramLabel getDiagramLabelForLabel(ElementLabel elementLabel) {
		return GmfModelsUtils.getDiagramLabelForLabel(elementLabel, getCanvas());
	}

	// Tool model
	
	public ToolRegistry getToolRegistry() {
		return toolRegistry;
	}

	public Palette getPalette() {
		return this.toolRegistry.getPalette();
	}
	
	public AbstractTool getToolForElement(Element element) {
		ToolRegistry toolRegistry = getToolRegistry();
		for (TreeIterator<EObject> i = toolRegistry.eAllContents(); i.hasNext(); ) {
			EObject o = i.next();
			if (o instanceof CreationTool) {
				CreationTool tool = (CreationTool) o;
				if (("Create "+element.getName()).equals(tool.getTitle())) {
					return tool;
				}
			}
		}
		return null;
	}

	// Mapping model

	public Mapping getMapping() {
		return mapping;
	}

	// Meta model
	
	public EPackage getMetaModel() {
		return metaModel;
	}
	
	public EClass getMetaModelEClass(String className) {
		return MetaModelUtils.getMetaModelEClass(this.metaModel, className);
	}
	
	public EAttribute getMetaModelEAttribute(
				String containerClassName, String containerAttributeName) {
		return MetaModelUtils.getMetaModelEAttribute(getMetaModel(),
				containerClassName, containerAttributeName);
	}

	public EReference getMetaModelEReference(
				String containerClassName, String containerReferenceName) {
		return MetaModelUtils.getMetaModelEReference(getMetaModel(),
							containerClassName, containerReferenceName);
	}

	// Setters

	public void setCanvas(Canvas canvas) {
		this.canvas = canvas;
	}

	public void setToolRegistry(ToolRegistry toolRegistry) {
		this.toolRegistry = toolRegistry;
	}

	public void setMapping(Mapping mapping) {
		this.mapping = mapping;
	}

	public void setMetaModel(EPackage metaModel) {
		this.metaModel = metaModel;
	}

}
